#include <stdio.h>

//#define DEBUG
#define ENG_PACKED
//#define FUNC_LIMITED

#define MCU_MSP430F2272	0
#define MCU_MSP430F5172	1
#define MCU_STM8S105K6	2

#define	HW_AVT_PETER	1	/* AVT:  5" EPD (sony) without AP */
#define	HW_AVT_XIA	2	/* AVT:  5" EPD (sony) with AT91 */
#define HW_ONYX_6	3	/* ONYX: 6" EPD with MX508 */
#define HW_AVT_PETER6	4	/* AVT:  6" EPD (sony) with avt2210 */
#define HW_AVT_SHANG6	5	/* AVT:  6" EPD (youyiyue) with AT91 */
#define HW_AVT_LGTEST6  6       /* AVT:  6" Light Guide Test, w/o AP */
#define HW_AVT_1301S6A  7       /* AVT:  6" released 1301S6A */
#define HW_AVT_SJ10     8       /* AVT:  10" picture frame by SJ */

#define HW_AVT_PETER6L	0x0201	/* AVT:  6" Low Cost version */
#define HW_AVT_ZHX6L	0x0202	/* AVT:  6" matrix version by ZHX */
#define HW_AVT_ZHOU6L	0x0203	/* AVT:  6" EPD with AT91 */
#define HW_AVT_ZHOU6LX	0x0204	/* AVT:  6" EPD with AT91 with switch */
#define HW_AVT_QIN6	0x0205	/* AVT:  6" EPD with AT91, PT receive */


#define SW_AVT_PETER	1
#define SW_AVT_REG	2	/* AVT: synaptics-like registers based */
#define SW_AVT_MSG	3	/* AVT: zForce-like message based */

/* versions */
#define SW_VERSION	SW_AVT_MSG
#define HW_VERSION 	HW_AVT_ZHOU6LX

#if (HW_VERSION >> 8) == MCU_MSP430F2272
#include <msp430f2272.h>
#define swab16(x) (x)
#define swab32(x) (x)
#elif (HW_VERSION >> 8) == MCU_MSP430F5172
#include <msp430f5172.h>
#elif (HW_VERSION >> 8) == MCU_STM8S105K6
#undef ENG_PACKED
//#include <iostm8s105k6.h>
#include <intrinsics.h>
#include "stm8s_conf.h"
#define swab16(x) ((u16)(				\
	(((u16)(x) & (u16)0x00ffU) << 8) |		\
	(((u16)(x) & (u16)0xff00U) >> 8)))
#define swab32(x) ((u32)(				\
	(((u32)(x) & (u32)0x000000ffUL) << 24) |	\
	(((u32)(x) & (u32)0x0000ff00UL) <<  8) |	\
	(((u32)(x) & (u32)0x00ff0000UL) >>  8) |	\
	(((u32)(x) & (u32)0xff000000UL) >> 24)))

#define BIT0                (0x01u)
#define BIT1                (0x02u)
#define BIT2                (0x04u)
#define BIT3                (0x08u)
#define BIT4                (0x10u)
#define BIT5                (0x20u)
#define BIT6                (0x40u)
#define BIT7                (0x80u)

/* precision delay macro */
#define DELAY_1_CYCLE()   do {nop();} while (0)
#define DELAY_2_CYCLES()  do {DELAY_1_CYCLE();nop();} while (0)
#define DELAY_3_CYCLES()  do {DELAY_2_CYCLES();nop();} while (0)
#define DELAY_4_CYCLES()  do {DELAY_3_CYCLES();nop();} while (0)
#define DELAY_5_CYCLES()  do {DELAY_4_CYCLES();nop();} while (0)	
#define DELAY_6_CYCLES()  do {DELAY_5_CYCLES();nop();} while (0)
#define DELAY_7_CYCLES()  do {DELAY_6_CYCLES();nop();} while (0)
#define DELAY_8_CYCLES()  do {DELAY_7_CYCLES();nop();} while (0)
#define DELAY_9_CYCLES()  do {DELAY_8_CYCLES();nop();} while (0)
#define DELAY_10_CYCLES() do {DELAY_9_CYCLES();nop();} while (0)
#define DELAY_12_CYCLES() do {DELAY_10_CYCLES();DELAY_2_CYCLES();} while (0)
#define DELAY_14_CYCLES() do {DELAY_10_CYCLES();DELAY_4_CYCLES();} while (0)
#define DELAY_15_CYCLES() do {DELAY_10_CYCLES();DELAY_5_CYCLES();} while (0)
#define DELAY_20_CYCLES() do {DELAY_10_CYCLES();DELAY_10_CYCLES();} while (0)
#define DELAY_22_CYCLES() do {DELAY_20_CYCLES();DELAY_2_CYCLES();} while (0)
#define DELAY_25_CYCLES() do {DELAY_20_CYCLES();DELAY_5_CYCLES();} while (0)
#define DELAY_28_CYCLES() do {DELAY_20_CYCLES();DELAY_8_CYCLES();} while (0)
#define DELAY_30_CYCLES() do {DELAY_20_CYCLES();DELAY_10_CYCLES();} while (0)
#define DELAY_32_CYCLES() do {DELAY_30_CYCLES();DELAY_2_CYCLES();} while (0)
#define DELAY_38_CYCLES() do {DELAY_30_CYCLES();DELAY_8_CYCLES();} while (0)
#define DELAY_40_CYCLES() do {DELAY_30_CYCLES();DELAY_10_CYCLES();} while (0)
#define DELAY_45_CYCLES() do {DELAY_40_CYCLES();DELAY_5_CYCLES();} while (0)
#define DELAY_48_CYCLES() do {DELAY_40_CYCLES();DELAY_8_CYCLES();} while (0)
#define DELAY_50_CYCLES() do {DELAY_40_CYCLES();DELAY_10_CYCLES();} while (0)
#define DELAY_53_CYCLES() do {DELAY_50_CYCLES();DELAY_3_CYCLES();} while (0)
#define DELAY_56_CYCLES() do {DELAY_50_CYCLES();DELAY_6_CYCLES();} while (0)
#define DELAY_60_CYCLES() do {DELAY_50_CYCLES();DELAY_10_CYCLES();} while (0)
#define DELAY_61_CYCLES() do {DELAY_60_CYCLES();DELAY_1_CYCLE();} while (0)
#define DELAY_64_CYCLES() do {DELAY_60_CYCLES();DELAY_4_CYCLES();} while (0)
#define DELAY_69_CYCLES() do {DELAY_60_CYCLES();DELAY_9_CYCLES();} while (0)
#define DELAY_70_CYCLES() do {DELAY_60_CYCLES();DELAY_10_CYCLES();} while (0)
#define DELAY_77_CYCLES() do {DELAY_70_CYCLES();DELAY_7_CYCLES();} while (0)
#define DELAY_80_CYCLES() do {DELAY_70_CYCLES();DELAY_10_CYCLES();} while (0)
#define DELAY_90_CYCLES() do {DELAY_80_CYCLES();DELAY_10_CYCLES();} while (0)

/* microsecond delay based on 16MHz cpu master frequency */
#define DELAY_1_US()  do {DELAY_10_CYCLES();DELAY_6_CYCLES();} while (0)
#define DELAY_2_US()  do {DELAY_1_US();DELAY_1_US();} while (0)
#define DELAY_3_US()  do {DELAY_2_US();DELAY_1_US();} while (0)
#define DELAY_4_US()  do {DELAY_3_US();DELAY_1_US();} while (0)
#define DELAY_5_US()  do {DELAY_4_US();DELAY_1_US();} while (0)
#define DELAY_6_US()  do {DELAY_5_US();DELAY_1_US();} while (0)
#define DELAY_7_US()  do {DELAY_6_US();DELAY_1_US();} while (0)
#define DELAY_8_US()  do {DELAY_7_US();DELAY_1_US();} while (0)
#define DELAY_9_US()  do {DELAY_8_US();DELAY_1_US();} while (0)
#define DELAY_10_US() do {DELAY_9_US();DELAY_1_US();} while (0)
extern u8 current_led;
#endif

#if (HW_VERSION >> 8) != MCU_STM8S105K6
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long int u32;
typedef signed char s8;
typedef signed short s16;
typedef signed long int s32;
#endif

#define I2C_SLAVE_ADDRESS	0x50

/* Clock settings */
#if (HW_VERSION >> 8) == MCU_MSP430F2272
#define MSP430_MCLK		16	/* in Mhz */
#define MSP430_SMCLK		8	/* in Mhz */
#elif (HW_VERSION >> 8) == MCU_STM8S105K6
#define STM8_MCLK		16	/* in Mhz */
#endif

/* IR LED/PD configuration */
#if (HW_VERSION == HW_ONYX_6) || (HW_VERSION == HW_AVT_SHANG6)
#define PD_COLS		12
#define PD_ROWS		16
#define SCREEN_WIDTH	916		/* in .1mm */
#define SCREEN_HEIGHT	1234
#define ADJ_X		0
#define ADJ_Y		0
#elif (HW_VERSION == HW_AVT_PETER6) || (HW_VERSION == HW_AVT_LGTEST6) || (HW_VERSION == HW_AVT_1301S6A) || (HW_VERSION == HW_AVT_PETER6L) || (HW_VERSION == HW_AVT_ZHX6L) || (HW_VERSION == HW_AVT_ZHOU6L) || (HW_VERSION >= HW_AVT_ZHOU6LX)
#define PD_COLS		13
#define PD_ROWS		17
#define SCREEN_WIDTH	906		/* in .1mm */
#define SCREEN_HEIGHT	1224
#define ADJ_X		0
#define ADJ_Y		0
#elif (HW_VERSION == HW_AVT_SJ10)
#define PD_COLS		11
#define PD_ROWS		17
#define SCREEN_WIDTH	1560		/* 4:3 */
#define SCREEN_HEIGHT	2080
#define ADJ_X		0
#define ADJ_Y		0
#else
#define PD_COLS		10		/* the number of vertical photodiodes */
#define PD_ROWS		13		/* the number of horizontal PDs */
#define SCREEN_WIDTH	770		/* in .1mm */
#define SCREEN_HEIGHT	1020
#define ADJ_X		0
#define ADJ_Y		0
#endif
#define LED_COLS	(PD_COLS - 1)	/* the number of vertical IR LED */
#define LED_ROWS	(PD_ROWS - 1)
#define BEAM_COLS	(LED_COLS * 2)	/* a LED can emit two beams */
#define BEAM_ROWS	(LED_ROWS * 2)
#if SW_VERSION == SW_AVT_REG
#define SCREEN_WIDTH	600
#define SCREEN_HEIGHT	800
#endif

#define IR_ROW_CHN	1		/* ADC1/A0 by IR_OE2/P4.5 */
#define IR_COL_CHN	0		/* ADC2/A1 by IR_OE1/P4.4 */

#if (HW_VERSION == HW_AVT_PETER6) || (HW_VERSION == HW_AVT_LGTEST6) || (HW_VERSION == HW_AVT_1301S6A) || (HW_VERSION == HW_AVT_SJ10) || (HW_VERSION == HW_AVT_PETER6L) || (HW_VERSION == HW_AVT_ZHX6L) || (HW_VERSION == HW_AVT_ZHOU6L) || (HW_VERSION >= HW_AVT_ZHOU6LX)
#define MIN_PULSE_WIDTH	1		/* 0.4us */
//#define MIN_PULSE_WIDTH	7		/* 3.1us */
#define MAX_PULSE_WIDTH	11		/* 5.1us */
#define DUTY_WTIME	50		/* 50us, wait 50us*2 after switch PD */
#else
#define MIN_PULSE_WIDTH	1		/* 0.4us */
#define MAX_PULSE_WIDTH	6		/* 2.6us */
#define DUTY_WTIME	32
#endif
#define STEP_PULSE	1
#if (HW_VERSION == HW_AVT_ZHOU6L) || (HW_VERSION == HW_AVT_ZHOU6LX)
#define MIN_INTENSITY	15
#define MAX_INTENSITY	15
#undef  MIN_PULSE_WIDTH
#define MIN_PULSE_WIDTH 3
#else
#define MIN_INTENSITY	1		/* max series resistor */
#define MAX_INTENSITY	15		/* min series resistor */
#endif

#define ADC_DEPTH_MAX		10
#ifdef ENG_PACKED
typedef u8 eng_t;
#define ENG_SHRINK(eng)		(eng)
#define ENG_SHRINK_U8(eng)	(eng)
#define ADC_VAL_MAX		(((1 << ADC_DEPTH_MAX) - 1) >> 2)
#define CAL_ENG_ABS_COL		100
#define CAL_ENG_ABS_ROW		100
#define RATIO_PEN_DOWN		30	/* threshold of touch down */
#else
typedef u16 eng_t;
#define ENG_SHRINK(eng)		((eng) >> 2)
inline static u8 ENG_SHRINK_U8(eng_t eng) { if (eng > 1023) return 255; else return eng >> 2; }
#define ADC_VAL_MAX		((1 << ADC_DEPTH_MAX) - 1)
#define CAL_ENG_ABS_COL		160	/* it is the shrinked value */
#define CAL_ENG_ABS_ROW		160
#define RATIO_PEN_DOWN		64	/* threshold of touch down */
#endif
#define RATIO_PEN_EDGE		5	/* threshold of touch area's edge */
#define NORM_GT(blk, ref, ratio) ((u16)(blk)*50/(ratio)*2) >= (ref)
#define NORM_LT(blk, ref, ratio) ((u16)(blk)*50/(ratio)*2) < (ref)
#define NORM_VAL(blk, ref)       ((u16)(blk)*50/((ref)+1)*2)
#define NUM_SAMPLES_NOISE	2	/* noise supress with multi-sample */
#define FREQ_SAMPLES_NOISE	60	/* scan freq for noise supress */
#define SCAN_ENG_ABS_MIN	2
#define SCAN_ENG_ABS_MID	4

#define NUM_TOUCH		2	/* 2 is dual-touch */
#define NUM_BEAMS_DUALTOUCH	5	/* two adjacent points */
#define PEN_SIZE_MIN		1	/* in mm */
#define PEN_SIZE_MAX		31	/* in mm */

/***************************** SW_AVT_REG ************************************/

/* I2C Registers */
#define MAX_REG_LEN		8
#define MAX_COOR_CNT		8	/* 16-bit x 2 in every coordinate */
#define BURST_DATA_BYTES	9

#define VERSION_REG		0x00
#define MODE_REG		0x01
#define STATUS_REG		0x02
#define INTERRUPT_EN_REG	0x03
#define COMMAND_REG		0x04
#define RUN_RATE_REG		0x05
#define STANDBY_RATE_REG	0x06
#define DEBUG_REG		0x07
#define DATA_REG		0x10 /* support block read at most 32 bytes */

/* I2C Register bits */

/* Device Mode Register Bits (MODE_REG) */
#define MODE_DEEP_SLEEP		0x00
#define MODE_RUN		0x01
#define MODE_STANDBY_MSK	0xf0

/* Interrupt Enable Register Bits (INTERRUPT_EN_REG) */
#define ABS_INT			0x01
#define TOUCH_INT		0x02

/* Device Command Register Bits (COMMAND_REG) */
#define RESET_COMMAND		0x01

/* Device Status Register Masks (STATUS_REG) */
#define CONFIGURED_MSK		0x80
#define COORD_CNT_MSK		0x0f
#define FIX_PULSE_REQUEST       0X40 
#define LED_LEVEL_REQUEST       0X20
#define FIX_LED_REQUEST         0X10
#define LED_NEIGHBOR_REQUEST    0X08

/* Device Debug Register Bits (DEBUG_REG) */
#define FORMAT_ABS              0x00
#define FORMAT_RAW_ALL		0x01

#if defined(__arm__) && defined(__ARMCC_VERSION) 
    // 
    // Setup PACKing macros for KEIL/RVMDK Tools 
    // 
    #define PACK_STRUCT_BEGIN __packed 
    #define PACK_STRUCT_STRUCT  
    #define PACK_STRUCT_END 
    #define PACK_STRUCT_FIELD(x) x 
#elif defined(__GNUC__)
    // 
    // Setup PACKing macros for GCC Tools 
    // 
    #define PACK_STRUCT_BEGIN 
    #define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) 
    #define PACK_STRUCT_END 
    #define PACK_STRUCT_FIELD(x) x 
#else
    // 
    // Setup PACKing macros for IAR Tools 
    // 
    #define PACK_STRUCT_BEGIN
    #define PACK_STRUCT_STRUCT 
    #define PACK_STRUCT_END
    #define PACK_STRUCT_FIELD(x) x 
#endif 


struct pen_coor_t {
	unsigned short x;
	unsigned short y;
	unsigned char pressure;
	unsigned char flags;
};

struct adc_quad_t {
	unsigned char col;	/* [0 .. BEAM_COLS-1] */
	unsigned char row;	/* [0 .. BEAM_ROWS-1] */
	unsigned char num_col;
	unsigned char num_row;
};

/***************************** SW_AVT_MSG ************************************/
#if HW_VERSION == HW_ONYX_6
#define VER_MAJOR 1
#define VER_MINOR 0
#define VER_REV   3
#else
#define VER_MAJOR 0
#define VER_MINOR 0x86
#define VER_REV   HW_VERSION
#endif

#define CMD_Deactivate			0x00	/* Arg 0, Res 1 */
#define CMD_Activate			0x01	/* Arg 0, Res 1 */
#define CMD_SetResolution		0x02	/* Arg 4, Res 1 */
#define CMD_SetConfiguration		0x03	/* Arg 4, Res 1 */
#define CMD_TouchDataRequest		0x04	/* Arg 0, Res 9*n */
#define CMD_TouchDataInternal		0x05	/* -,     Res 2+x+y */
#define CMD_SetScanningFrequency	0x08	/* Arg 2, Res 1 */
#define CMD_SetPenSize			0x09	/* Arg 2, Res 1 */
#define CMD_VersionRequest		0x0A	/* Arg 0, Res 8 */
#define CMD_LowSignalAlert		0x0D	/* -    , Res 2+x+y */
#define CMD_FixedPulseStrength		0x0F	/* Arg 1, Res 2+x+y */
#define CMD_ForceCalibration		0x1A	/* Arg 0, Res 0 */
#define CMD_LedLevelRequest		0x1C	/* Arg 0, Res 2+3(x+y) */
#define CMD_SetActiveLeds		0x1D	/* Arg 4, Res 1 */
#define CMD_StatusCommand		0x1E	/* Arg 0, Res 60 */
#define CMD_ScanFixedLed		0x1F	/* Arg 2, Res 1+n */
#define CMD_ScanLedNeighbor		0x2F	/* Arg 1, Res 2+(x+y) */
#define CMD_EnterBSL			0xEB	/* Arg 0, Res 0 */
#define CMD_SetAlt			0xF0	/* Arg 8, Res 1 */
#define CMD_SetAlt2			0xF2	/* Arg 4, Res 1 */
#define CMD_InvalidCommand		0xFE	/* -    , Res 1 */

#define FRAME_START		0xEE
#define MESSAGES_BUF_LEN	256

struct Resolution {
	unsigned short width;
	unsigned short height;
};
struct ConfigurationData {
	unsigned long int flags;
};
struct ActiveLeds {
	unsigned char x_Start;
	unsigned char x_End;
	unsigned char y_Start;
	unsigned char y_End;
};

struct VersionResponse {
	unsigned short major;
	unsigned short minor;
	unsigned short build;
	unsigned short revision;
};

struct LowSignalInfo {
	u8 PDSignal2Low : 4;
	u8 PDSignal1Low : 4; //high is beam0
};

struct LowSignalAlertResponse {
	u8 xCount;
	u8 yCount;
	struct LowSignalInfo xLEDS[LED_COLS];
	struct LowSignalInfo yLEDS[LED_ROWS];
};

struct FixedPulseStrengthResponse {
	u8 xCount;
	u8 yCount;
	u8 xValues[BEAM_COLS];
	u8 yValues[BEAM_ROWS];
};

struct LedSignalInfo {
	unsigned char LedStrength2 : 4;
	unsigned char LedStrength1 : 4;
	unsigned char PDSignal1;
	unsigned char PDSignal2;
};

struct LedLevelResponse {
	u8 xCount;
	u8 yCount;
	struct LedSignalInfo xLEDS[LED_COLS];
	struct LedSignalInfo yLEDS[LED_ROWS];
};


#define PEN_DOWN	0
#define PEN_MOVE	1
#define PEN_UP		2
/*
 * 15..13 12..8  7..6   5..2 1   0
 * xSizeLo3, ySize, state, id,  xSizeHi2
 */
#define PACK_XY_ATTR(state, id, xs, ys) \
	(((state) << 6) | ((id) << 2) | \
	 (((xs) & 0x18) >> 3) | (((xs) & 0x07) << 13) | ((ys) << 8))

PACK_STRUCT_BEGIN
#ifdef __IAR_SYSTEMS_ICC__
#if (HW_VERSION >> 8) != MCU_STM8S105K6
#pragma pack(1)
#endif
#endif

struct CoordinateData {
	unsigned short x;
	unsigned short y;
	unsigned short attr;
	unsigned char probability;
} PACK_STRUCT_STRUCT;

struct ScanningFrequencyData {
	unsigned char idleFrequency;
	unsigned char fullScanningFrequency;
	unsigned char sampFreq;
} PACK_STRUCT_STRUCT;

struct PulseSignalInfo {
	u8 strength : 4;
	u8 time : 4;
	u8 ledn;
} PACK_STRUCT_STRUCT;

struct range_t {
	u8 min : 4;
	u8 max : 4;
};

//----------------------Configure Byte 0------------------------------------	
#define CONFIG_SINGLE_TOUCH	(1UL << 0)  //0 - dual touch, 1 - single
#define CONFIG_DEBUG_INTERNAL	(1UL << 6)  //0 - disable,    1 - enable
#define CONFIG_CHECK_PENSIZE	(1UL << 7)  //0 - skip check, 1 - check
//----------------------Configure Byte 1------------------------------------	
#define CONFIG_DEJITTER		(1UL << 8)  //0 - disable,    1 - enable
//----------------------Configure Byte 2------------------------------------	
#define CONFIG_IRQ_EDGE		(1UL << 16) //0 - low level,  1 - edge
#define CONFIG_LOW_ALERT	(1UL << 20) //0 - no alert,   1 - enable alert
#define CONFIG_NO_TOGGLE	(1UL << 21) //0 - toggle Vref/Vop/IrTC
#define CONFIG_DEBUG_ROW	(1UL << 22) //DEBUG_INTERNAL
#define CONFIG_DEBUG_COL	(1UL << 23) //DEBUG_INTERNAL
//----------------------Configure Byte 3------------------------------------	
#define CONFIG_DEBUG_REVERSE	(1UL << 24) //DEBUG_INTERNAL
#define CONFIG_NO_SCAN		(1UL << 30) //0 - scan pen down, 1 - no scan
#define CONFIG_NO_EXPERIMENT	(1UL << 31) //0 - experiment code

struct SettingsData {
	struct VersionResponse version;
	unsigned char active;
	unsigned short counter;
	struct ConfigurationData config;
//----------------------Configure Byte end----------------------------------
	struct ScanningFrequencyData freq;
	struct Resolution resolution;
	struct ActiveLeds activeLeds;
	u8 pen_size_min;		//@26  0 - disable check
	u8 pen_size_max;		//@27
	u8 b28;
	u16 width_mm;                   //@29
	u16 height_mm;                  //@31
	u16 touch_cnt_total;            //@33
	u16 touch_cnt_sent;             //@35
	u8 b37;
	u8 b38;
	u8 b39;
	u8 b40;
	u8 b41;
	u8 coord_idx_get;               //@42
	u8 coord_idx_put;               //@43
	u8 coord_cnt;                   //@44
	u8 coord1_status;               //@45
	u8 coord2_status;               //@46
	u8 b47;
	u8 b48;
	u8 b49;
	u8 b50;
	u8 b51;
	/* SetAlt */
//----------------------Alt Byte 0----------------------------------
	u8 cal_eng_abs_row;
	u8 cal_eng_abs_col;
	u8 thr_pen_edge;
	u8 thr_pen_down;
//----------------------Alt Byte 1----------------------------------
	u8 scan_eng_abs_min : 4;
	u8 scan_eng_abs_mid : 4;
	u8 duty_wtime : 6;
	u8 num_samples_noise : 2;
	struct range_t range_it;
	struct range_t range_tm;
	s8 adj_x;
	s8 adj_y;
	u8 rsv[4];
} PACK_STRUCT_STRUCT;
extern struct SettingsData settings;


#ifdef __IAR_SYSTEMS_ICC__
#if (HW_VERSION >> 8) != MCU_STM8S105K6
#pragma pack()
#endif
#endif
PACK_STRUCT_END

/* internal format */
struct coord_t {
	u16 lpBStw25SiVyI;
	u16 yNpWPggyZT9VA;
	u16 x;
	u16 y;

	u8 state : 2;
	u8 id    : 1;
	u8 xsize : 5;

	u8 ysize : 5;
	u8 rsv   : 3;

	u8 prob;
};

extern void aat4292_a2s(u8 port, u8 chn);
extern void udelay(unsigned short);

//#define PD_SET_DELAY	udelay(settings.duty_wtime*4)
#define PD_SET_DELAY

#include "hw_avt_xia.h"
#include "hw_onyx_6.h"
#include "hw_avt_peter6.h"
#include "hw_avt_shang6.h"
#include "hw_avt_lgtest6.h"
#include "hw_avt_1301s6a.h"
#include "hw_avt_sj10.h"
#include "hw_avt_peter6l.h"
#include "hw_avt_zhx6l.h"
#include "hw_avt_zhou6l.h"
#include "hw_avt_zhou6lx.h"
#include "hw_avt_qin6a.h"


#ifndef OPAMP_RESET
#define OPAMP_RESET()
#define OPAMP_RUN()
#define OPAMP_RUN1()
#define OPAMP_HOLD()
#endif

/* wait 150us to make OPAMP stable, but onyx claims 56us*4 */
#define OPAMP_ON()   do { VOP_SW_ON; VREF_SW_ON; udelay(300); } while (0)
#define OPAMP_OFF()  do { VOP_SW_OFF; VREF_SW_OFF; } while (0)

#define jRY1cRHWG2XgEv35DWvDIZqWBLhK1 static
#define msBdfdTLdBxGb3uporDRLSDsYva70 mslastBdfdTLdBxGb3uporDRLSDsYvastat70
#define sCwJa8sdmY9M6p2zqDh8sQD5RTy0 const
#define g1ZGh0VDGKDAZEXUjEBeJVygEIdvnJ float
#define AAObDnPooa4MI3ZMoF1LS3usspEl1 struct nt1ZcuyoPGmsbbCELKjrBnQMLr9ff
#define EDU2LUu4gHCY29rjHyzuSMO79rqAnnQb5b95A u8
#define To4Ys2woyUTK22taiHSccNhexjO u16
#define aURR45NGS1qNRFKLb2HBsWeFBhJctSmGwKomkqclyjzn4ElHTO PEN_UP
#define hm4aD9Wy2eY PEN_DOWN
#define YAcP9aLL5M PEN_MOVE

extern u8 fw_status;
extern struct PulseSignalInfo fix_ps;
extern struct coord_t g_coords[2];
extern u32 bitmap_x;
extern u32 bitmap_y;
extern u8 current_hz;
extern u8 timer_pending;

extern void init_i2c(void);
extern void init_adc(void);
extern void init_timer(void);
extern void disable_i2c(void);
extern void enable_i2c(void);
extern void disable_timer(void);
extern void enable_timer(void);
extern void reload_timer(unsigned char);
extern void switch_adc(unsigned char);
extern void start_led_adc(unsigned char intensity, unsigned char time);
extern eng_t get_adc_sample(void);

extern void measure_neighbor(u8, u8);
extern const u8 intensity_fixup[];
#define START_LED_ADC(it, tm)	start_led_adc(intensity_fixup[it], tm)

extern void calibration(void);
extern void engine(void);

extern void compute_pen_location(void);
extern void i2c_session_run(void);
extern void emit_pen_up(void);
extern s8 append_msg_resp(u8 cmd, u8 *body, u8 cnt);

#ifdef DEBUG

#define BUG() \
	do { __disable_interrupt(); GREEN_LED_ON(); printf("%s:%d\n", __FILE__, __LINE__); while (1); } while (0)
#define debug(fmt,args...)	printf(fmt, ##args)

#else

#define BUG() \
	do { __disable_interrupt(); GREEN_LED_ON(); while (1); } while (0)
#define debug(fmt,args...)

#endif

#if 1
#define assert(condition)
#else
#define assert(condition) \
	do { if (!(condition)) BUG(); } while(0)
#endif
